#!/usr/bin/env python
# -*- coding:utf-8 -*-

import time

from cellcache import CellCache

from key import ROW_KEY_MIN, ROW_KEY_MAX, Key

#######################################################################

class   Range(object) :
    '''

    * compose key before insert/scan Range
    * Range work in 2 mode : READ, WRITE
    * WRITE MODE :
        insert record into cell-cache
        save cell-cache into cell-store
    * READ MODE :
        scan first cell-cache and cell-store
    '''
    def __init__(self, name, store_dir, min_key=ROW_KEY_MIN, max_key=ROW_KEY_MAX) :
        self.name = name
        self.store_dir = store_dir
        self.opened = False

        self.min_key = min_key
        self.max_key = max_key
        if self.min_key > self.max_key :
            self.min_key, self.max_key = self.max_key, self.min_key

        self._cache = CellCache(store_dir)
        # __init__()

    def open(self) :
        if self.opened : return True

        self.opened = True
        return True
        # open()

    def close(self) :
        if not self.opened : return True

        self.opened = False
        return True
        # close()

    def setKeyInterval(self, min_key, max_key) :
        self.min_key = min_key
        self.max_key = max_key
        if self.min_key > self.max_key :
            self.min_key, self.max_key = self.max_key, self.min_key
        # setKeyInterval()

    ###################################################################

    def getCurrentTimestamp(self) :
        timestamp = int(time.time())
        return timestamp
        # getCurrentTimestamp()

    def isAcceptableKey(self, row_key) :
        # self.min_key <= row_key < self.max_key
        return (row_key >= self.min_key) and (row_key < self.max_key)
        # isAcceptableKey()

    def acceptKey(self, row_key) :
        if (row_key < self.min_key) or (row_key >= self.max_key) :
            raise AcceptKeyError, 'Key %s NOT accepted by range "%s"' % (`row_key`, self.name)
        # acceptKey()

    ###################################################################

    def insert(self, row_key, columns, timestamp=None) :
        if not row_key :
            raise EmptyKeyError
        self.acceptKey(row_key)
        if timestamp is None :
            timestamp = self.getCurrentTimestamp()

        for family,qualifier,data in columns :
            if not family :
                raise ColumnFamilyError, 'Empty column family for key %s' % `row_key`
            if not data :
                raise ValueError, 'Empty Data for key %s' % `row_key`
            if not qualifier : qualifier = ''

            key = Key(row_key, family, qualifier, Key.FLAG_INSERT, timestamp)
            self._cache.insert(row_key, key.key, data)
        # insert()

    def erase(self, row_key, columns=None, timestamp=None) :
        if not row_key :
            raise EmptyKeyError
        self.acceptKey(row_key)
        if timestamp is None :
            timestamp = self.getCurrentTimestamp()

        if columns is None :
            # delete row
            key = Key(row_key=row_key, flag=Key.FLAG_DELETE_ROW, timestamp=timestamp)
            self._cache.insert(row_key, key.key, '')
        else :
            # delete some column family
            raise NotImplementedError, 'Erase Column Family Not Implemented.'
        # erase()

    ###################################################################

    class   Scanner(object) :
        def __init__(self, range_instance, scan_context, timeout) :
            self.range_instance = range_instance
            self.scan_context = scan_context
            self.timeout = timeout
            # __init__()

        def __iter__(self) :
            return self
            # __iter__()

        def next(self) :
            raise StopIteration
            # next()

        def _prescan(self) :
            pass
            # _prescan()

        # class Scanner

    def createScanner(self, context, timeout=3600) :
        scanner = self.__class__.Scanner(self, context, timeout)
        return scanner
        # createScanner()

    ###################################################################

    def compact(self) :
        pass
        # merge()

    # class Range

